/**
 * 所有版权归 广西梧州 陈锦韬 所有
 *
 * @Title: MutilTableInterceptor
 * @Package com.rx.core.dbase
 * @Description: 双表内联
 * @author: 陈锦韬
 * @date: 2021\7\22 0022
 * @version V1.0
 * @Copyright: 2021 陈锦韬  All rights reserved.
 */
package com.rx.core.dbase.mutil;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.rx.core.dbase.AbstractSqlHandler;
import com.rx.core.dbase.mutil.param.*;
import com.rx.core.util.EmptyChecker;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.util.HashMap;
import java.util.Properties;

/**
 * @author: Administrator
 * @Description: 双表内联
 * @date: 2021\7\22 0022
 */
@Intercepts({
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
        ,@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})
//        ,@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
@Slf4j
public class MutilTableInterceptor extends AbstractSqlHandler implements Interceptor {

    private Object getValueFormHashMap(HashMap map,String name){
        try{
            if (EmptyChecker.isEmpty(map)){
                return null;
            }
            return map.get(name);
        }catch (Exception e){

        }
        return null;
    }
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] queryArgs = invocation.getArgs();

        Object parameter = queryArgs[1];

        if (parameter instanceof DoubleInnerParameter){
            return intercept(invocation,(MutilTableParameter)parameter,(e)->((DoubleInnerParameter)e).getSql(),null);
        }else if (parameter instanceof DoubleUnionInnerParameter){
            return intercept(invocation,(MutilTableParameter)parameter,(e)->((DoubleUnionInnerParameter)e).getSql(),null);
        }else if (parameter instanceof DoubleUnionLeftParameter){
            return intercept(invocation,(MutilTableParameter)parameter,(e)->((DoubleUnionLeftParameter)e).getSql(),null);
        }else if (parameter instanceof DoubleLeftJoinParameter){
            return intercept(invocation,(MutilTableParameter)parameter,(e)->((DoubleLeftJoinParameter)e).getSql(),null);
        }else if (parameter instanceof ThreeInnerParameter){
            return intercept(invocation,(MutilTableParameter)parameter,(e)->((ThreeInnerParameter)e).getSql(),null);
        }else if (parameter instanceof ThreeInnerLeftPageParameter){
            return intercept(invocation,(MutilTableParameter)parameter,(e)->((ThreeInnerLeftPageParameter)e).getSql(),null);
        }else if ( parameter instanceof MapperMethod.ParamMap ){
            // parameter instanceof HashMap  windows 可以。linux不行
            // TODO:坑人。windows 可以是arg0 linux 不行。改用param1
            Object page = getValueFormHashMap((MapperMethod.ParamMap) parameter,"param1");
            if (EmptyChecker.isEmpty(page)){
                return invocation.proceed();
            }
            log.info("first parameter:" + page.getClass().getName());
            if(page instanceof IPage){
                Object param= getValueFormHashMap((MapperMethod.ParamMap) parameter,"param2");
                if (EmptyChecker.isEmpty(param)){
                    return invocation.proceed();
                }
                log.info("second parameter:" + param.getClass().getName());

                if(param instanceof DoubleInnerParameter){
                    return intercept(invocation,(MutilTableParameter)param,(e)->((DoubleInnerParameter)param).getSql(),(IPage)page);
                }else if(param instanceof DoubleUnionInnerParameter){
                    return intercept(invocation,(MutilTableParameter)param,(e)->((DoubleUnionInnerParameter)param).getSql(),(IPage)page);
                }else if(param instanceof DoubleUnionLeftParameter){
                    return intercept(invocation,(MutilTableParameter)param,(e)->((DoubleUnionLeftParameter)param).getSql(),(IPage)page);
                }else if(param instanceof DoubleLeftJoinParameter){
                    return intercept(invocation,(MutilTableParameter)param,(e)->((DoubleLeftJoinParameter)param).getSql(),(IPage)page);
                }else if(param instanceof ThreeInnerParameter){
                    return intercept(invocation,(MutilTableParameter)param,(e)->((ThreeInnerParameter)param).getSql(),(IPage)page);
                }else if(param instanceof ThreeInnerLeftPageParameter){
                    return intercept(invocation,(MutilTableParameter)param,(e)->((ThreeInnerLeftPageParameter)param).getSql(),(IPage)page);
                }
            }
        }
        return invocation.proceed();
    }

    /**
     * 产生代理对象
     * @param target
     * @return
     */
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        log.info("MutilTableInterceptor：设置配置");
    }
}
